package cn.com.lms.app.api.exam;

import cn.com.lms.app.api.exam.dto.EmployeePaperSubjectAddDTO;
import cn.com.lms.app.api.exam.dto.UserTestDTO;
import cn.com.lms.app.api.exam.vo.*;
import cn.com.lms.business.core.constant.ErrorEnum;
import cn.com.lms.business.core.util.SystemUserUtil;
import cn.com.lms.business.exam.enums.PaperTypeEnum;
import cn.com.lms.business.exam.enums.SubjectTypeEnum;
import cn.com.lms.business.exam.persistence.entity.EmployeePaper;
import cn.com.lms.business.exam.persistence.entity.EmployeePaperSubject;
import cn.com.lms.business.exam.service.*;
import cn.com.lms.business.exam.utils.BeanListUtils;
import cn.com.lms.business.exam.utils.JsonUtil;
import cn.com.lms.business.learning.service.LearningPlanService;
import cn.com.lms.business.user.persistence.entity.SysUserVo;
import com.bnzj.core.exception.BusinessException;
import com.bnzj.core.rest.ResponseResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * @author zhangzhenjiang
 * @createDate 2020/3/23
 * @description
 */
@Tag(name = "试卷", description = "试卷")
@RestController
@RequestMapping("/app/api/paper")
public class PaperApi {

    @Autowired
    EmployeePaperSubjectService employeePaperSubjectService;

    @Autowired
    QuestionSubjectService questionSubjectService;

    @Autowired
    PaperSubjectService paperSubjectService;

    @Autowired
    EmployeePaperService employeePaperService;

    @Autowired
    EmployeePaperStageService employeePaperStageService;

    @Autowired
    private LearningPlanService planService;

    @Operation(summary = "提交试题", description = "提交试题")
    //@PostMapping("/subjectSave")
    @PostMapping(value="/subjectSave",produces="application/json;charset=UTF-8")
    public ResponseResult<List<EmployeePaperSubject>> addEmployeePaperSubject(@RequestBody EmployeePaperSubjectAddDTO employeePaperSubjectAddDTO) {
        SysUserVo sysUser = SystemUserUtil.getCurrentUser();
        if (sysUser != null) {
            employeePaperSubjectAddDTO.setEmployeeId(sysUser.getId());
        } else {
            employeePaperSubjectAddDTO.setEmployeeId(10116166L);
        }
        Optional<EmployeePaper> employeePaperOpt = employeePaperService.findById(employeePaperSubjectAddDTO.getEmployeePaperId());
        if (!employeePaperOpt.isPresent()) {
            throw new BusinessException(ErrorEnum.RECORD_NOT_EXIST.getMessage(), "" + ErrorEnum.RECORD_NOT_EXIST.getCode());
        }
        EmployeePaper employeePaper = employeePaperOpt.get();
        EmployeePaperStageDetailVO employeePaperStageDetailVO = null;

        // 试卷试题
        List<EmployeeSubjectAnswerVO> employeeSubjectAnswerVOList = employeePaperSubjectAddDTO.getEmployeeSubjectAnswerVOList();

        List<Map<String, Object>> paperSubjectMapList = paperSubjectService.findPaperSubjectByPaperId(employeePaperSubjectAddDTO.getPaperId());

        List<EmployeePaperSubject> employeePaperSubjectList = new CopyOnWriteArrayList<>();
        Integer totalScore = 0;
        Boolean isHand = employeePaperSubjectAddDTO.getIsHandle();
        List<Integer> scoreList = new CopyOnWriteArrayList<>();
        employeeSubjectAnswerVOList.stream().forEach(employeeSubjectAnswerVO -> {
            List<Map<String, Object>> mapList = paperSubjectMapList.stream().filter(m -> employeeSubjectAnswerVO.getSubjectId().longValue() == ((Number) m.get("subjectId")).longValue()).collect(Collectors.toList());
            if (mapList.size() > 0) {
                Map<String, Object> paperSubjectMap = mapList.get(0);
                EmployeePaperSubject employeePaperSubject = JsonUtil.fromMap(paperSubjectMap, EmployeePaperSubject.class);
                employeePaperSubject.setAnswer(employeeSubjectAnswerVO.getAnswer());
                // 计算得分
                Integer score = 0;
                if (employeePaperSubject.getAnswer().equals(employeePaperSubject.getRightAnswer()) && (SubjectTypeEnum.SINGLE_OPTION.getValue().equals(employeePaperSubject.getType()) || SubjectTypeEnum.MULTIPLE_OPTION.getValue().equals(employeePaperSubject.getType()) || SubjectTypeEnum.JUDGE.getValue().equals(employeePaperSubject.getType()))) {
                    score = employeePaperSubject.getSubjectScore();
                    scoreList.add(employeePaperSubject.getSubjectScore());
                }
                employeePaperSubject.setScore(score);
                employeePaperSubject.setAnswer(employeeSubjectAnswerVO.getAnswer());
                employeePaperSubject.setEmployeeId(employeePaperSubjectAddDTO.getEmployeeId());
                employeePaperSubject.setEmployeePaperId(employeePaperSubjectAddDTO.getEmployeePaperId());
                employeePaperSubjectList.add(employeePaperSubject);
            }
        });

        Short type = employeePaper.getType();

        if (isHand && type == 1) {
            Map employeePaperStageDetailVOMap = employeePaperStageService.findEmployeePaperByEmployeePaperId(employeePaper.getId());
            if (employeePaperStageDetailVOMap.size() > 0) {
                employeePaperStageDetailVO = JsonUtil.fromMap(employeePaperStageDetailVOMap, EmployeePaperStageDetailVO.class);
            }


        }
        totalScore = scoreList.stream().collect(Collectors.summingInt(Number::intValue));
        employeePaper.setIsHand(isHand);
        if (isHand) {
            employeePaper.setModifyTime(new Date());
        }
        employeePaper.setGrade(totalScore);
        employeePaper.setRemainTime(employeePaperSubjectAddDTO.getRemainTime());
        List<EmployeePaperSubject> result = employeePaperSubjectService.savePaperSubject(employeePaperSubjectList, employeePaper, employeePaperStageDetailVO);
        return ResponseResult.success(result);
    }


    @Operation(summary = "开始测验", description = "开始测验")
    //@PostMapping("/userTest")
    @PostMapping(value="/userTest",produces="application/json;charset=UTF-8")
    public ResponseResult<EmployeePaperStageDetailVO> userTest(@RequestBody UserTestDTO userTestDTO) {
        SysUserVo sysUser = SystemUserUtil.getCurrentUser();
        if (sysUser != null) {
            userTestDTO.setUserId(sysUser.getId());
        } else {
            userTestDTO.setUserId(10072506L);
        }
        //记录学员已参加过计划记录
        if (null != userTestDTO.getPlanId()) {
//            planService.savePlanJoinRecord(userTestDTO.getPlanId());
        }
        Long employeeId = userTestDTO.getUserId();
        Long stageDetailId = userTestDTO.getStageDetailId();
        List<Map> mapList = employeePaperStageService.findEmployeePaperByStageDetailIdAndEmployeeId(stageDetailId, employeeId);
        Optional<Map> optMap = mapList.stream().filter(m -> Boolean.FALSE.equals(m.get("isHand"))).findFirst();
        EmployeePaperStageDetailVO employeePaperStageDetailVO = new EmployeePaperStageDetailVO();
        if (!optMap.isPresent()) {
            // 开始测验
            employeePaperService.saveStageEmployeePaper(userTestDTO);
            List<Map> mapList2 = employeePaperStageService.findEmployeePaperByStageDetailIdAndEmployeeId(stageDetailId, employeeId);
            Optional<Map> optMap2 = mapList2.stream().filter(m -> m.get("isHand").equals(false)).findFirst();
            Map map2 = optMap2.get();
            employeePaperStageDetailVO = JsonUtil.fromMap(map2, EmployeePaperStageDetailVO.class);
            employeePaperStageDetailVO.setIsPass(false);
        } else {
            // 继续测验
            Map map = optMap.get();
            employeePaperStageDetailVO = JsonUtil.fromMap(map, EmployeePaperStageDetailVO.class);
            employeePaperStageDetailVO.setIsPass(false);
        }
        List<PaperSubjectVO> paperSubjectVOList = new CopyOnWriteArrayList<>();
        if (PaperTypeEnum.FIXED_SELECTION.getValue().equals(employeePaperStageDetailVO.getPaperType())) {
            // 查询固定试卷试题
            paperSubjectVOList = paperSubjectService.getPaperSubjectVOList(employeePaperStageDetailVO.getPaperId());
            employeePaperStageDetailVO.setPaperSubjectVOList(paperSubjectVOList);
        }
        if (PaperTypeEnum.RANDOM_QUESTION.getValue().equals(employeePaperStageDetailVO.getPaperType())) {
            paperSubjectVOList = paperSubjectService.findRadomQuestionSubjectByPaperIdList(employeeId, employeePaperStageDetailVO.getPaperId());
            if (CollectionUtils.isEmpty(paperSubjectVOList)) {
                // 试卷生成随机试题
                Number paperSingleScore = employeePaperStageDetailVO.getSingleScore();
                Number paperMultipleScore = employeePaperStageDetailVO.getMultipleScore();
                Number paperJudgeScore = employeePaperStageDetailVO.getJudgeScore();
                List<PaperSubjectVO> subjectList = paperSubjectService.radomPaperSubject(employeePaperStageDetailVO.getPaperId(), paperSingleScore, paperMultipleScore, paperJudgeScore);
                employeePaperStageDetailVO.setPaperSubjectVOList(subjectList);
                // 保存随机试卷试题
                paperSubjectService.batchSaveRandPaperSubject(employeePaperStageDetailVO, employeeId.toString());

            } else {
                employeePaperStageDetailVO.setPaperSubjectVOList(paperSubjectVOList);
            }
        }


        List<Map<String, Object>> employeePaperSubjectMapList = employeePaperSubjectService.findByEmployeePaperId(employeePaperStageDetailVO.getEmployeePaperId().longValue());
        List<UserSubjectAnswerVO> userSubjectAnswerVOList = new CopyOnWriteArrayList<>();
        if (!CollectionUtils.isEmpty(employeePaperSubjectMapList)) {
            userSubjectAnswerVOList = BeanListUtils.mapListToObjectList(employeePaperSubjectMapList, UserSubjectAnswerVO.class);
            userSubjectAnswerVOList.stream().forEach(userSubjectAnswerVO -> {
                if (userSubjectAnswerVO.getAnswer().equals("false") || userSubjectAnswerVO.getAnswer().equals("正确")) {
                    userSubjectAnswerVO.setAnswer("A");
                }
                if (userSubjectAnswerVO.getAnswer().equals("true") || userSubjectAnswerVO.getAnswer().equals("错误")) {
                    userSubjectAnswerVO.setAnswer("B");
                }
            });
        }
        employeePaperStageDetailVO.setUserSubjectAnswerVOList(userSubjectAnswerVOList);
        return ResponseResult.success(employeePaperStageDetailVO);

    }


    @Operation(summary = "根据id查询阶段测验详情", description = "阶段测验详情")
    @GetMapping("/test/detail/{stageDetailId}")
    public ResponseResult<UserPaperDetailVO> getUserTestDetailById(HttpServletRequest request, @Parameter(name = "stageDetailId", description = "阶段详情ID", required = true) @PathVariable("stageDetailId") Long stageDetailId) {
        Long employeeId = 10000000L;
        SysUserVo sysUser = SystemUserUtil.getCurrentUser();
        String userId = request.getParameter("userId");
        if (!StringUtils.isEmpty(userId)) {
            sysUser.setId(Long.valueOf(userId));
        }
        if (sysUser != null) {
            employeeId = sysUser.getId();
        }
        List<UserPaperDetailVO> userPaperDetailVOList = new ArrayList<>();
        List<Map> mapList = employeePaperStageService.findEmployeePaperByStageDetailIdAndEmployeeId(stageDetailId, employeeId);
        Optional<Map> passOpt = mapList.stream().filter(m -> m.get("isHand").equals(true) && Integer.valueOf(m.get("grade").toString()) >= Integer.valueOf(m.get("adoptScore").toString())).findFirst();
        if (passOpt.isPresent()) {
            Map passMap = passOpt.get();
            // 考试通过
            UserPaperDetailVO passUserPaperDetailVO = new UserPaperDetailVO();
            passUserPaperDetailVO.setIsPass(true);
            EmployeePaperStageDetailVO passEmployeePaperStageDetailVO = JsonUtil.fromMap(passMap, EmployeePaperStageDetailVO.class);
            passUserPaperDetailVO.setPaperName(passEmployeePaperStageDetailVO.getPaperName());
            List<EmployeePaperSubjectVO> employeePaperSubjectList = new CopyOnWriteArrayList<>();
            List<Map<String, Object>> paperMapList = employeePaperSubjectService.findByEmployeePaperId(passEmployeePaperStageDetailVO.getEmployeePaperId().longValue());
            if (!CollectionUtils.isEmpty(mapList)) {
                employeePaperSubjectList = BeanListUtils.mapListToObjectList(paperMapList, EmployeePaperSubjectVO.class);
                employeePaperSubjectList.stream().forEach(employeePaperSubject -> {
                    if (SubjectTypeEnum.JUDGE.getValue().intValue() == employeePaperSubject.getType().intValue()) {
                        employeePaperSubject.setOptions("A 正确###B 错误");
                        if (employeePaperSubject.getAnswer().equals("false") || employeePaperSubject.getAnswer().equals("正确")) {
                            employeePaperSubject.setAnswer("A");
                        }
                        if (employeePaperSubject.getAnswer().equals("true") || employeePaperSubject.getAnswer().equals("错误")) {
                            employeePaperSubject.setAnswer("B");
                        }
                    }

                });
            }
            passUserPaperDetailVO.setEmployeePaperSubjectVOList(employeePaperSubjectList);
            return ResponseResult.success(passUserPaperDetailVO);
        } else {
            Optional<Map> optMap = mapList.stream().filter(m -> m.get("isHand").equals(false)).findFirst();

            UserPaperDetailVO userPaperDetailVO = new UserPaperDetailVO();
            if (optMap.isPresent()) {
                Map map = optMap.get();
                // 继续考试，开始考试
                userPaperDetailVO.setIsPass(false);
                EmployeePaperStageDetailVO employeePaperStageDetailVO = JsonUtil.fromMap(map, EmployeePaperStageDetailVO.class);
                userPaperDetailVO.setPaperName(employeePaperStageDetailVO.getPaperName());
                List<EmployeePaperSubjectVO> employeePaperSubjectList = new CopyOnWriteArrayList<>();
                List<Map<String, Object>> paperMapList = employeePaperSubjectService.findByEmployeePaperId(employeePaperStageDetailVO.getEmployeePaperId().longValue());
                if (!CollectionUtils.isEmpty(paperMapList)) {
                    employeePaperSubjectList = BeanListUtils.mapListToObjectList(paperMapList, EmployeePaperSubjectVO.class);
                    employeePaperSubjectList.stream().forEach(employeePaperSubject -> {
                        if (SubjectTypeEnum.JUDGE.getValue().intValue() == employeePaperSubject.getType().intValue()) {
                            employeePaperSubject.setOptions("A 正确###B 错误");
                            if (employeePaperSubject.getAnswer().equals("false") || employeePaperSubject.getAnswer().equals("正确")) {
                                employeePaperSubject.setAnswer("A");
                            }
                            if (employeePaperSubject.getAnswer().equals("true") || employeePaperSubject.getAnswer().equals("错误")) {
                                employeePaperSubject.setAnswer("B");
                            }
                        }

                    });
                }
                userPaperDetailVO.setEmployeePaperSubjectVOList(employeePaperSubjectList);
                userPaperDetailVOList.add(userPaperDetailVO);
            } else {
                Optional<Map> notPassOptMap = mapList.stream().filter(m -> m.get("isHand").equals(true) && Integer.valueOf(m.get("grade").toString()) < Integer.valueOf(m.get("adoptScore").toString())).findFirst();

                UserPaperDetailVO notPassUserPaperDetailVO = new UserPaperDetailVO();
                if (notPassOptMap.isPresent()) {
                    Map notPassEmployeePaperStageDetailVOMap = notPassOptMap.get();
                    // 考试未通过 ，返回最近一次考试的试卷
                    notPassUserPaperDetailVO.setIsPass(false);
                    EmployeePaperStageDetailVO notPassemployeePaperStageDetailVO = JsonUtil.fromMap(notPassEmployeePaperStageDetailVOMap, EmployeePaperStageDetailVO.class);
                    notPassUserPaperDetailVO.setPaperName(notPassemployeePaperStageDetailVO.getPaperName());
                    List<EmployeePaperSubjectVO> employeePaperSubjectList = new CopyOnWriteArrayList<>();
                    List<Map<String, Object>> paperMapList = employeePaperSubjectService.findByEmployeePaperId(notPassemployeePaperStageDetailVO.getEmployeePaperId().longValue());
                    if (!CollectionUtils.isEmpty(paperMapList)) {
                        employeePaperSubjectList = BeanListUtils.mapListToObjectList(paperMapList, EmployeePaperSubjectVO.class);
                        employeePaperSubjectList.stream().forEach(employeePaperSubject -> {
                            if (SubjectTypeEnum.JUDGE.getValue().intValue() == employeePaperSubject.getType().intValue()) {
                                employeePaperSubject.setOptions("A 正确###B 错误");
                                if (employeePaperSubject.getAnswer().equals("false") || employeePaperSubject.getAnswer().equals("正确")) {
                                    employeePaperSubject.setAnswer("A");
                                }
                                if (employeePaperSubject.getAnswer().equals("true") || employeePaperSubject.getAnswer().equals("错误")) {
                                    employeePaperSubject.setAnswer("B");
                                }
                            }

                        });
                    }
                    notPassUserPaperDetailVO.setEmployeePaperSubjectVOList(employeePaperSubjectList);
                    userPaperDetailVOList.add(notPassUserPaperDetailVO);
                    return ResponseResult.success(notPassUserPaperDetailVO);
                }

            }
            return ResponseResult.success(userPaperDetailVO);
        }

    }


    @Operation(summary = "根据id查询阶段详情", description = "阶段详情")
    @GetMapping("/test/stage/detail/{stageDetailId}")
    public ResponseResult<UserTestLearnStageDetailVO> getUserTestLearnStageDetailVOById(HttpServletRequest request, @Parameter(name = "stageDetailId", description = "阶段详情ID", required = true) @PathVariable("stageDetailId") Long stageDetailId) {
        Long employeeId = 10000000L;
        SysUserVo sysUser = SystemUserUtil.getCurrentUser();
        if (sysUser != null) {
            employeeId = sysUser.getId();
        }
        UserTestLearnStageDetailVO userTestLearnStageDetailVO = new UserTestLearnStageDetailVO();
        TestLearnStageDetailVO testLearnStageDetailVO = employeePaperStageService.getTestLearningStageDetail(stageDetailId);
        if (testLearnStageDetailVO == null) {
            throw new BusinessException(ErrorEnum.RECORD_NOT_EXIST.getMessage(), "" + ErrorEnum.RECORD_NOT_EXIST.getCode());
        }
        userTestLearnStageDetailVO.setTestLearnStageDetailVO(testLearnStageDetailVO);

        List<Map> mapList = employeePaperStageService.findEmployeePaperByStageDetailIdAndEmployeeId(stageDetailId, employeeId);
        Optional<Map> passOpt = mapList.stream().filter(m -> m.get("isHand").equals(true) && Integer.valueOf(m.get("grade").toString()) >= Integer.valueOf(m.get("adoptScore").toString())).findFirst();

        if (passOpt.isPresent()) {
            // 考试通过
            Map passEmployeePaperStageDetailVOMap = passOpt.get();
            EmployeePaperStageDetailVO passEmployeePaperStageDetailVO = JsonUtil.fromMap(passEmployeePaperStageDetailVOMap, EmployeePaperStageDetailVO.class);
            passEmployeePaperStageDetailVO.setIsPass(true);
            userTestLearnStageDetailVO.setEmployeePaperStageDetailVO(passEmployeePaperStageDetailVO);
        } else {
            // 开始考试，继续考试
            Optional<Map> optMap = mapList.stream().filter(m -> m.get("isHand").equals(false)).findFirst();
            if (optMap.isPresent()) {
                Map employeePaperStageDetailVOMap = optMap.get();
                EmployeePaperStageDetailVO employeePaperStageDetailVO = JsonUtil.fromMap(employeePaperStageDetailVOMap, EmployeePaperStageDetailVO.class);
                employeePaperStageDetailVO.setIsPass(false);
                userTestLearnStageDetailVO.setEmployeePaperStageDetailVO(employeePaperStageDetailVO);
            } else {
                Optional<Map> notPassOptMap = mapList.stream().filter(m -> m.get("isHand").equals(true) && Integer.valueOf(m.get("grade").toString()) < Integer.valueOf(m.get("adoptScore").toString())).findFirst();
                if (notPassOptMap.isPresent()) {
                    // 考试未通过
                    Map notPassEmployeePaperStageDetailVOMap = notPassOptMap.get();
                    EmployeePaperStageDetailVO notPassEmployeePaperStageDetailVO = JsonUtil.fromMap(notPassEmployeePaperStageDetailVOMap, EmployeePaperStageDetailVO.class);
                    notPassEmployeePaperStageDetailVO.setIsPass(false);
                    userTestLearnStageDetailVO.setEmployeePaperStageDetailVO(notPassEmployeePaperStageDetailVO);
                }
            }
        }
        return ResponseResult.success(userTestLearnStageDetailVO);
    }


}
